package com.livegoods.redisdao;

import com.livegoods.pojo.House;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public class HouseDao4RedisImpl  implements HouseDao4Redis{


    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public House get(String key) {
        return (House) redisTemplate.opsForValue().get(key);
    }

    /**
     * redis 出现异常会回滚事务，释放资源，但是异常会一直往上抛出 try...finally ,开发者需要手动处理异常 try...cache
     *
     * @param key
     * @param value
     * @return
     */
    @Override
    public boolean set(String key, Object value) {

        try{
            redisTemplate.setEnableTransactionSupport(true);
            Object result = redisTemplate.execute(new SessionCallback<List<Object>>() {

                @Override
                public  List<Object> execute(RedisOperations redisOperations) throws DataAccessException {

                    //获取redis缓存的House
                    House house = (House)redisOperations.opsForValue().get(key);

                    //如果为true，说明已经预定了，返回null
                    if(house.isRented()){
                        return  null;
                    }

                    //开启事务队列，通知其他操作，当前操作是原子操作，大家排队
                    redisTemplate.multi();

                    //修改redis缓存数据
                    redisOperations.opsForValue().set(key,value);

                    //类似于提交事务操作
                    List exec = redisOperations.exec();
                    return exec;
                }
            });
            redisTemplate.setEnableTransactionSupport(false);
            if(result == null){
                return false;
            }
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return  false;
        }
    }
}
